﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using Wicture.DbRESTFul;
using Wicture.DbRESTFul.SQL;
using Wicture.EPC.Common;
using Wicture.EPC.Service.V1.Models;
using Wicture.EPC.Service.V1.Repository;

namespace Wicture.EPC.Service.V1.QueryInterceptors.Interceptors
{
    public class HondaQueryInterceptor : BaseQueryInterceptor
    {
        private string[] brandCodes = new string[] { "honda", "acura" };

        public override string[] BrandCodes => brandCodes;

        public override object QueryModel(DbRESTFulRepository repository, JObject request)
        {
            var param = request.ToObject<Get_Model_InfoParam>();
            Get_Model_InfoResult result = null;
            Get_Model_InfoResult._MultiModel multiModel = null;
            string featureCodes = null;
            dynamic model = null;
            if (!string.IsNullOrEmpty(param.vin))
            {
                if (param.vin.Length == 17)
                {
                    var prefix = $"{param.vin.Substring(0, 8)}*{param.vin.Substring(9, 2)}";
                    var sequence = param.vin.Substring(9);
                    var queryParam = new JObject();
                    queryParam["prefix"] = prefix;
                    queryParam["sequence"] = sequence;
                    queryParam["brandCode"] = param.brandCode;
                    if (!string.IsNullOrEmpty(param.selectorId))
                    {
                        queryParam["selectorId"] = param.selectorId;
                    }
                    IEnumerable<dynamic> list = repository.Invoke(CSIs.Get_Model_By_Vin_For_Honda, queryParam);
                    if (list.Count() == 0)
                    {
                        throw new LogicalException($"未找到该Vin码(Honda){param.vin}！", 610);
                    }
                    else if (list.Count() > 1)
                    {
                        multiModel = new Get_Model_InfoResult._MultiModel
                        {
                            title = "选择配置",
                            param = new List<string> { "selectorId" },
                            header = new List<Get_Model_InfoResult._props> { new Get_Model_InfoResult._props { key = "area", value = "地区" }, new Get_Model_InfoResult._props { key = "transGrade", value = "变速箱 / 等级" }, new Get_Model_InfoResult._props { key = "features", value = "设备" } },
                            content = list.Select(q => new Get_Model_InfoResult._MultiModel._content { area = q.area }).ToList()
                        };
                        var allFeatureStr = string.Join(",", list.Select(x => x.featureCodes));
                        var featureCodeList = allFeatureStr.Split(',', StringSplitOptions.RemoveEmptyEntries);
                        IEnumerable<Feature> features = repository.Invoke<Feature>(CSIs.Query_Vin_Features, new { featureCodes = featureCodeList });
                        var contentList = new List<Get_Model_InfoResult._MultiModel._content>();
                        foreach (var info in list)
                        {
                            var contentItem = new Get_Model_InfoResult._MultiModel._content { area = info.area, selectorId = info.selectorId?.ToString(), transGrade = $"{info.transmissionType} / {info.grade}" };
                            string featureStr = info.featureCodes;
                            var fAarray = featureStr.Split(',', StringSplitOptions.RemoveEmptyEntries);
                            contentItem.features = string.Join("$$", features.Where(q => fAarray.Contains(q.featureCode)).Select(x => $"{x.featureCode}({x.description})"));
                            contentList.Add(contentItem);
                        }
                        multiModel.content = contentList;
                    }
                    model = list.ElementAt(0);
                    model.vin = param.vin;
                }
                else
                {
                    throw new LogicalException("VIN格式不对！", 612);
                }
            }
            else
            {
                var ids = param.id.Split("_");
                if (ids.Count() > 1)
                {
                    param.id = ids[1];
                }
                model = repository.Invoke(CSIs.Get_Model_For_Honda, param);
            }

            if (model != null)
            {
                featureCodes = model.featureCodes;
                result = JObject.FromObject(model).ToObject<Get_Model_InfoResult>();
                result.props = new List<Get_Model_InfoResult._props>
                    {
                        new Get_Model_InfoResult._props{ key = "车型", value = model.name },
                        new Get_Model_InfoResult._props{ key = "年款", value = model.productionYear },
                        new Get_Model_InfoResult._props{ key = "变速箱", value = model.transmissionType },
                        new Get_Model_InfoResult._props{ key = "车架号", value = param.vin },
                        new Get_Model_InfoResult._props{ key = "DOORS", value = model.doors },
                        new Get_Model_InfoResult._props{ key = "AREA", value = model.area },
                        new Get_Model_InfoResult._props{ key = "MFTREPC", value = model.productionAreaCode },
                        new Get_Model_InfoResult._props{ key = "GRADE", value = model.grade }
                    };
            }
            if (multiModel != null)
            {
                result.multiModel = multiModel;
            }

            if (!string.IsNullOrEmpty(featureCodes))
            {
                var featureCodeList = featureCodes.Split(",");
                IEnumerable<Feature> features = repository.Invoke<Feature>(CSIs.Query_Vin_Features, new { featureCodes = featureCodeList });
                result.features = new List<Get_Model_InfoResult._features>();
                foreach (var feature in features)
                {
                    result.features.Add(new Get_Model_InfoResult._features() { key = feature.featureName, value = feature.description });
                }
            }
            return result;
        }

        protected override List<Query_MainGroupResult> GetMainGroup(DbRESTFulRepository repository, JObject param)
        {
            return repository.Invoke<Query_MainGroupResult>(CSIs.Query_Main_Group_For_Not_Have_Model, param);
        }

        public override object QueryPartDetail(DbRESTFulRepository repository, JObject param)
        {
            var partId = param.Value<string>(ParamFields._partId);
            dynamic data = null;
            if (string.IsNullOrEmpty(partId))
            {

                data = repository.Invoke(CSIs.Get_Part_Detail_For_Honda, param);
            }
            else
            {
                string marketCode = param.Value<string>(ParamFields._marketCode);
                if (string.IsNullOrEmpty(marketCode))
                {
                    param[ParamFields._marketCode] = "";
                }
                data = repository.Invoke(CSIs.Get_Usage_Detail_For_Honda, param);
            }
            if (data == null) return null;
            Query_Part_DetailResult result = JObject.FromObject(data).ToObject<Query_Part_DetailResult>();

            if (!string.IsNullOrEmpty(partId))
            {
                IEnumerable<Part_Price> partAttrs = repository.Invoke<Part_Price>(CSIs.Get_Part_Price, new { result.partCode });
                partAttrs = partAttrs.Where(q => !q.marketCode.Equals(result.marketCode));
                if (partAttrs.Any())
                {
                    result.partAttributes = partAttrs.Select(q => new Query_Part_DetailResult._partAttribute
                    {
                        partCode = q.partCode,
                        marketCode = q.marketCode,
                        marketName = q.marketName,
                        brandCode = q.brandCode,
                        brandName = BrandDictionary.GetName(q.brandCode),
                        cost = q.cost,
                        price = q.price,
                        stock = q.stock,
                        priceUpdatedAt = q.priceUpdatedAt,
                        priceFC = q.priceFC,
                        props = new List<Query_Part_DetailResult._prop> { new Query_Part_DetailResult._prop { key = "厂商", value = q.marketName } }
                    }).ToList();
                }
            }

            //4.配件附加属性处理
            var props = new List<Query_Part_DetailResult._prop>
            {
                new Query_Part_DetailResult._prop { key = "英文名", value = result.partNameEn ?? string.Empty },
                new Query_Part_DetailResult._prop { key = "件数", value = result.quantity ?? string.Empty },
                new Query_Part_DetailResult._prop { key = "备注", value = result.remark ?? string.Empty }
            };
            result.props = props.Where(q => !string.IsNullOrEmpty(q.value)).ToList();

            return result;
        }

        public override object QueryParts(DbRESTFulRepository repository, JObject param)
        {
            List<Query_PartsResult> result = repository.Invoke<Query_PartsResult>(CSIs.Query_Parts_For_Honda, param);

            return result;
        }

        protected override IEnumerable<Query_SubGroupResult> GetSubGroup(DbRESTFulRepository repository, JObject param)
        {
            return repository.Invoke<Query_SubGroupResult>(CSIs.Query_SubGroup_For_Honda, param);
        }
        protected override dynamic GetModelsByPart(DbRESTFulRepository repository, int pageIndex, int pageSize, string brandCode, string partCode)
        {
            return repository.Invoke(CSIs.Query_Models_By_Part_For_Honda, new { pageIndex, pageSize, brandCode, partCode });
        }

        protected override dynamic GetHotPointsByPart(DbRESTFulRepository repository, string brandCode, string partCode, IEnumerable<string> imageIds)
        {
            return repository.Invoke(CSIs.Query_HotPoints_By_Part_For_Honda, new { brandCode, partCode, imageIds });
        }

        protected override List<Query_SubGroupResult> BuildSubGroupResults(List<Query_SubGroupResult> result)
        {
            return result;
        }
        protected override List<Query_SubGroupResult> FilterSubGroupsByVin(DbRESTFulRepository repository, List<Query_SubGroupResult> results, JObject param)
        {
            return results;
        }
        protected override List<SearchSubGroupResults> GetSearchResults(DbRESTFulRepository repository, string brandCode, string[] partCodes, string selectorId)
        {
            return repository.Invoke<SearchSubGroupResults>(CSIs.Search_SubGroups_By_PartCodes_For_Honda, new { brandCode, partCodes, selectorId });
        }

        protected override List<QuickPartResult> QuickQueryParts(DbRESTFulRepository repository, IEnumerable<string> partCodes, string brandCode)
        {
            return repository.Invoke<QuickPartResult>(CSIs.Query_QuickParts_For_Honda, new { partCodes = partCodes, brandCode }); ;
        }

        protected override List<QuickPartResult> QuickQueryPartsFilterByMarket(DbRESTFulRepository repository, List<QuickPartResult> parts, int selectorId)
        {
            List<QuickPartResult> ret = new List<QuickPartResult>();
            if (parts != null && parts.Any())
            {
                string marketCode = string.Empty;
                var modelInfo = repository.Invoke(CSIs.Get_MarketCode_By_SelectorId, new { selectorId });
                if (modelInfo != null)
                {
                    marketCode = modelInfo.marketCode;
                }
                foreach (var item in parts)
                {
                    if (item.marketCode == marketCode)
                    {
                        ret.Add(item);
                    }
                }
            }
            return ret;
        }

        protected override List<MaintainPart> GetMaintainParts(DbRESTFulRepository repository, string selectorId)
        {
            List<MaintainPart> maintainParts = repository.Invoke<MaintainPart>(CSIs.Query_Maintain_Parts_By_SelectorId_For_Honda, new { selectorId });
            return maintainParts;
        }

        protected override List<PartCatalog> GetPartCatalogs(DbRESTFulRepository repository, IEnumerable<string> partCodes, string selectorId, string brandCode, string vinCode)
        {
            List<PartCatalogResult> partCatalogResults = repository.Invoke<PartCatalogResult>(CSIs.Query_Part_Catalog_For_Honda, new { selectorId, partCodes });
            if (!partCatalogResults.Any())
            {
                return new List<PartCatalog>();
            }
            var hotPointsModel = repository.Invoke(CSIs.Query_HotPoints_By_Parts_For_Honda, new { brandCode, partCodes = partCatalogResults.Select(q => q.partCode).Distinct(), subGroupIds = partCatalogResults.Select(q => q.subGroupId).Distinct() });
            JArray allPoints = JArray.FromObject(hotPointsModel);

            foreach (var item in partCatalogResults)
            {
                //2.1适用车型多张图片处理
                var imgs = allPoints.Where(p => p.Value<int>("subGroupId") == item.subGroupId).Select(p => p.Value<string>("url")).Distinct().Select(x => new _imgs { url = x }).ToList();
                foreach (var img in imgs)
                {
                    //2.1.1适用车型每张图片对应的热点处理
                    img.points = allPoints.Where(p => p.Value<string>("url") == img.url && p.Value<string>("sn") == item.sn)
                                       .Select(p => p.ToObject<_imgs._points>()).ToList();
                }
                item.imgs = imgs;
            }
            return BuildPartCatalogList(partCatalogResults);
        }

        protected override List<QuickPartResult> QuickQueryPartsFilterByUsage_Model(DbRESTFulRepository repository, List<QuickPartResult> parts, int selectorId)
        {
            List<QuickPartResult> ret = new List<QuickPartResult>();
            if (selectorId > 0 && parts != null && parts.Any())
            {
                List<string> partCodes = parts.Select(e => e.partCode).Distinct().ToList();

                List<Query_PartsResult> partUsages = repository.Invoke<Query_PartsResult>(CSIs.Quick_PartUsage_By_SelectorId_For_Honda, new { selectorId, partCodes });
                if (partUsages != null && partUsages.Any())
                {
                    foreach (var item in parts)
                    {
                        if (partUsages.FirstOrDefault(e => e.partCode == item.partCode) != null)
                        {
                            ret.Add(item);
                        }
                    }
                }
            }
            return ret;
        }

        protected override List<QuickPartResult> QuickQueryPartsFilterByUsage_Vin(DbRESTFulRepository repository, List<QuickPartResult> parts, int selectorId, string vin)
        {
            return QuickQueryPartsFilterByUsage_Model(repository, parts, selectorId);
        }
    }
}
